﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using MyWeb.Common.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace MyWeb.Extensions.ServiceExtensions.Filter
{
    /// <summary>
    /// 自定义过滤器
    /// </summary>
    public interface IFixedTokenFilter : IFilterMetadata
    {
        AuthorizationFilterContext OnAuthorization(AuthorizationFilterContext context);
    }
    //这里继承了IAllowAnonymous,所以只要加上[FixedToken]就相当于拥有了[AllowAnonymous]的特性
    public class FixedTokenAttribute : Attribute, IFixedTokenFilter, IAllowAnonymous
    {
        public AuthorizationFilterContext OnAuthorization(AuthorizationFilterContext context)
        {
            string? fixedtoken = string.Empty;
            //token过期或者token是无效随便输入的token,要求token过期也要能使用,就需要手动对token合法性进行验证
            if (!context.HttpContext.User.Identity.IsAuthenticated)
            {
                fixedtoken = context.HttpContext.Request.Headers["Authorization"];
                fixedtoken = fixedtoken?.Replace("Bearer ", "");
                //验证传过来的token不允许为空
                if (string.IsNullOrEmpty(fixedtoken))
                {
                    //context.Result就表示httpcontext已经终结了,不会在往下走了
                    context.Result = new ContentResult()
                    {
                        Content = new
                        {
                            result = "denied",
                            status = false,
                            code = (int)HttpStatusCode.Unauthorized,
                            message = "没有传入token"
                        }.ToString(),
                        ContentType = "application/json",
                        StatusCode = (int)HttpStatusCode.Unauthorized
                    };
                    return context;
                }
                //string userId = JwtHelper.GetUserId(fixedtoken);
                string userId = "";
                if (string.IsNullOrWhiteSpace(userId))
                {
                    //context.Result就表示httpcontext已经总结了,不会在往下走了
                    context.Result = new ContentResult()
                    {
                        Content = new
                        {
                            result = "denied",
                            status = false,
                            code = (int)HttpStatusCode.Unauthorized,
                            message = "token不正确"
                        }.ToString(),
                        ContentType = "application/json",
                        StatusCode = (int)HttpStatusCode.Unauthorized
                    };
                    return context;
                }
            }
            else
            {
                //页面传入的token和jwt生成token一致，并且token没有失效，可以用下面方式直接取token
                fixedtoken = ((ClaimsIdentity)context.HttpContext.User.Identity)?.BootstrapContext?.ToString();
            }
            IMemoryCache? cache = context.HttpContext.RequestServices.GetService(typeof(IMemoryCache)) as IMemoryCache;
            string? token = cache.Get<string>("newjwttoken");
            //判断当前用户的token与缓存的token是否相同(与缓存token做对比的作用是验证单机登陆,不允许多台设备同时登陆)
            if (token != "Bearer " + fixedtoken)
            {
                context.Result = new ContentResult()
                {
                    Content = new
                    {
                        result = "denied",
                        status = false,
                        code = (int)HttpStatusCode.Unauthorized,
                        message = "token已失效"
                    }.ToString(),
                    ContentType = "application/json",
                    StatusCode = (int)HttpStatusCode.Unauthorized
                };
                return context;
            }
            return context;
        }
    }


    //4：调用登陆接口的时候不需要验证,需要ILoginUserFilter 来标识
    public interface ILoginUserFilter : IFilterMetadata
    {

    }
    public class LoginUserAttribute : Attribute, ILoginUserFilter
    {

    }
}
